package com.upeoe.shiro.chapter4;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.converters.AbstractConverter;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.DefaultPasswordService;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.DefaultHashService;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.crypto.hash.format.DefaultHashFormatFactory;
import org.apache.shiro.crypto.hash.format.Shiro1CryptFormat;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.junit.Test;

/**
 * @author ven_hxz
 * @create 2016-07-04 上午10:03
 */
public class PasswordTutorial extends LoginHelper {
    @Test
    public void testPasswordServiceWithMyRealm() {
        login("classpath:shiro-password-service.ini", "root", "root");
    }

    @Test
    public void testPasswordServiceWithJdbcRealm() {
        login("classpath:shiro-jdbc-password-service.ini", "root", "root");
    }

    @Test
    public void testHashedCredentialsMatcherWithMyRealm2() {
        login("classpath:shiro-hashed-credentialsMatcher.ini", "guest", "guest");
    }

    @Test
    public void testHashedCredentialsMatcherWithJdbcRealm() {
        BeanUtilsBean.getInstance().getConvertUtils().register(new EnumConverter(), JdbcRealm.SaltStyle.class);
        login("classpath:shiro-jdbc-hashed-credentialsMatcher.ini", "guest", "guest");
    }

    @Test(expected = ExcessiveAttemptsException.class)
    public void testRetryLimitHashedCredentialsMatcherWithMyRealm() {
        for (int i = 0; i < 5; i++) {
            try {
                login("classpath:shiro-retryLimitHashedCredentialsMatcher.ini", "guest", "gue");
            } catch (Exception ignored) {
            }
        }
        login("classpath:shiro-retryLimitHashedCredentialsMatcher.ini", "guest", "gue");
    }

    @Test
    public void testGeneratePassword1() {
        DefaultPasswordService passwordService = new DefaultPasswordService();
        passwordService.setHashService(new DefaultHashService());
        passwordService.setHashFormat(new Shiro1CryptFormat());
        passwordService.setHashFormatFactory(new DefaultHashFormatFactory());

        System.out.println(passwordService.encryptPassword("root"));
    }

    @Test
    public void testGeneratePassword2() {
        String algorithmName = "md5";
        String username = "guest";
        String password = "guest";
        String salt1 = username;
        String salt2 = new SecureRandomNumberGenerator().nextBytes().toHex();
        int hashIterations = 2;

        SimpleHash hash = new SimpleHash(algorithmName, password, salt1 + salt2, hashIterations);
        String encodedPassword = hash.toHex();
        System.out.println(salt2);
        System.out.println(encodedPassword);
    }

    /**
     * Enum 转换器
     */
    private class EnumConverter extends AbstractConverter {

        @Override
        protected String convertToString(Object value) throws Throwable {
            return ((Enum) value).name();
        }

        protected Object convertToType(final Class aClass, Object o) throws Throwable {
            return Enum.valueOf(aClass, o.toString());
        }

        protected Class getDefaultType() {
            return null;
        }
    }
}
